#include "../s21_decimal.h"

int s21_get_bit(s21_decimal *value, int index) {
  if (index < 0 || index > MAX_INDEX) {
    return 0;
  }

  int integer = value->bits[index / 32];

  return (integer & 1u << (index % 32)) > 0 ? 1 : 0;
}

int s21_set_bit(s21_decimal *value, int index) {
  if (index < 0 || index > MAX_INDEX) {
    return ERROR;
  }

  value->bits[index / 32] |= 1u << (index % 32);

  return OK;
}

int s21_reset_bit(s21_decimal *value, int index) {
  if (index < 0 || index > MAX_INDEX) {
    return ERROR;
  }

  value->bits[index / 32] &= ~(1u << (index % 32));

  return OK;
}

int s21_get_sign(s21_decimal *value) {
  int integer = value->bits[LAST];

  return (integer & 1u << 31) > 0 ? NEGATIVE : POSITIVE;
}

int s21_set_sign(s21_decimal *value, int sing) {
  if (sing != POSITIVE && sing != NEGATIVE) {
    return ERROR;
  }

  if (sing == NEGATIVE) {
    value->bits[LAST] |= 1u << 31;
  } else {
    value->bits[LAST] &= ~(1u << 31);
  }

  return OK;
}

void s21_inverse_sign(s21_decimal *value) { value->bits[LAST] ^= 1u << 31; }

int s21_get_scale(s21_decimal *value) {
  int integer = value->bits[LAST];

  return (integer >> 16) & (0b11111111);
}

int s21_set_scale(s21_decimal *value, int scale) {
  if (scale < 0 || scale > 28) {
    return ERROR;
  }

  int sign = s21_get_sign(value);
  value->bits[LAST] = scale << 16;
  s21_set_sign(value, sign);

  return OK;
}